﻿using jvm.classfile;
using jvm.classfile.constantpool;
using jvm.rtda.heap.clazz.cp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace jvm.rtda.heap.clazz
{
    class JConstantPool
    {
        public JClass jClass;
        private object[] consts;

        public JConstantPool(JClass jClass, ConstantPool constantPool)
        {
            this.jClass = jClass;
            consts = new object[constantPool.constantInfos.Length];
            for (int i = 1; i < constantPool.constantInfos.Length; i++)
            {
                ConstantInfo constantInfo = constantPool.constantInfos[i];
                if (constantInfo.GetType() == typeof(ConstantIntegerInfo))
                    consts[i] = ((ConstantIntegerInfo)constantInfo).val;
                else if (constantInfo.GetType() == typeof(ConstantFloatInfo))
                    consts[i] = ((ConstantFloatInfo)constantInfo).val;
                else if (constantInfo.GetType() == typeof(ConstantLongInfo))
                {
                    consts[i] = ((ConstantLongInfo)constantInfo).val;
                    i++;
                }
                else if (constantInfo.GetType() == typeof(ConstantDoubleInfo))
                {
                    consts[i] = ((ConstantDoubleInfo)constantInfo).val;
                    i++;
                }
                else if (constantInfo.GetType() == typeof(ConstantStringInfo))
                    consts[i] = ((ConstantStringInfo)constantInfo).String();
                else if (constantInfo.GetType() == typeof(ConstantClassInfo))
                    consts[i] = new ClassRef(this, ((ConstantClassInfo)constantInfo).Name());
                else if (constantInfo.GetType() == typeof(ConstantFieldrefInfo))
                    consts[i] = new FieldRef(this, (ConstantFieldrefInfo)constantInfo);
                else if (constantInfo.GetType() == typeof(ConstantMethodrefInfo))
                    consts[i] = new MethodRef(this, (ConstantMemberrefInfo)constantInfo);
                else if (constantInfo.GetType() == typeof(ConstantInterfaceMethodrefInfo))
                    consts[i] = new InterfaceMethodRef(this, (ConstantInterfaceMethodrefInfo)constantInfo);
            }
        }

        public T GetConstant<T>(uint index)
        {
            object obj = consts[index];
            if (obj == null)
            {
                Console.WriteLine("No constants at index {0}", index);
                Environment.Exit(0);
            }
            return (T)obj;
        }
    }
}
